package org.hepeng.commons.spring.cloud.netflix.zuul;

import com.netflix.zuul.context.RequestContext;
import org.hepeng.commons.exception.ApplicationRuntimeException;
import org.springframework.cloud.netflix.zuul.web.ZuulController;
import org.springframework.util.Assert;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.Executor;

/**
 * @author he peng
 */
public class AsyncZuulController extends ZuulController {

    private Executor executor;

    public AsyncZuulController(Executor executor) {
        Assert.notNull(executor , "executor must not be null");
        this.executor = executor;
    }

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

        AsyncContext asyncContext = request.startAsync(request, response);
        this.executor.execute(() -> {
            try {
                AsyncZuulController.super.handleRequestInternal(request , response);
            } catch (Exception e) {
                throw new ApplicationRuntimeException(e);
            } finally {
                asyncContext.complete();
                RequestContext.getCurrentContext().unset();
            }
        });
        return null;
    }
}
